<?php

//
// +------------------------------------------------------------------------+
// | PHP Version 5.4                                                        |
// +------------------------------------------------------------------------+
// | Copyright (c) All rights reserved.                                     |
// +------------------------------------------------------------------------+
// | 世纪车来车往(北京）网络科技有限公司 版权所有！                         |
// | TEL:010-63732365  HOTLINE:400-6688-365  EMAIL:clcw@clcw.com.cn         |
// | $Revision: 1.0 $                                                       |
// +------------------------------------------------------------------------+
// | Author: liguohua@clcw.com.cn  Blog:http://blog.sina.com.cn/saverneo        |
// +------------------------------------------------------------------------+
//
// OneThink常量定义
const ONETHINK_VERSION = '1.1.141212';
const ONETHINK_ADDON_PATH = './Addons/';

/**
 * 计算交易服务费
 *
 * @param int    $price     初始价格
 * @param string $starttime 场开始时间
 *
 * @return float|int
 */
function get_commision($price, $starttime = '')
{
    $row = M('setting')->where(['name' => 'COMMISION_MIN_FEE'])->find();
    $arr = json_decode($row['remark'], true);
    if ($arr['is_avalible'] == '1') {
        if (date('Y-m-d', strtotime($starttime)) == $arr['startdate']) {
            $min_fee = $arr['commision'];
        } else {
            $min_fee = $row['value'];
        }
    } else {
        $min_fee = $row['value'];
    }
    $min_fee = intval($min_fee);


    $max_fee = M('setting')->where(['name' => 'COMMISION_MAX_FEE'])->getField('value');
    $max_fee = intval($max_fee);

    $percentage = M('setting')->where(['name' => 'COMMISION_PERCENTAGE'])->getField('value');
    $percentage = floatval($percentage);

    $p = $price * $percentage;
    if ($p <= $min_fee) {
        $p = $min_fee;
    } elseif ($p >= $max_fee) {
        $p = $max_fee;
    } else {
        $p = round($p / 100) * 100;
    }
    return $p;
}


/**
 * 获取计算交易服务费所需的配置参数
 *
 * @return mixed
 */
function get_commision_params_value()
{
    $condition['name'] = ['in', ['COMMISION_MIN_FEE', 'COMMISION_MAX_FEE', 'COMMISION_PERCENTAGE']];
    $conf_list = M("setting")->field('name,value')->where($condition)->select();
    $conf_arr = [];
    foreach ($conf_list as $k => $v) {
        $conf_arr[$v['name']] = $v['value'];
    }
    return $conf_arr;
}

/* 产生一个车辆编号
 * @param $type string 类型 car/order
 * @return string
 * */
function gen_car_no()
{
    $cdt = ['posttime' => ['like', date('Y-m-d') . '%']];
    $car = M('cars')->where($cdt)->order('car_id DESC')->find();
    if ($car) {
        preg_match("/C" . date('ymd') . "([\d]{2,4})/", $car['car_no'], $matches);
        $no = sprintf("%04d", ($matches[1] + 1));
    } else {
        $no = '0001';
    }
    return 'C' . date('ymd') . $no;
}

//
/* 产生一个拍单编号
 * @param $type string 类型 car/order
 * @return string
 * */
function gen_order_no()
{
    $cdt = ['create_time' => ['like', date('Y-m-d') . '%']];
    $o = M('order')->where($cdt)->order('order_id DESC')->find();
    if ($o) {
        preg_match("/P" . date('ymd') . "([\d]{2,4})/", $o['order_no'], $matches);
        $no = sprintf("%04d", ($matches[1] + 1));
    } else {
        $no = '0001';
    }
    return 'P' . date('ymd') . $no;
}


/**
 * 产生一个充值单号
 *
 * @param     $dealer_id
 * @param int $type 如果有类型依次更新
 *
 * @return string
 */
function gen_recharge_no($dealer_id, $type = 1)
{
    $recharge_type = [
        1 => "A" //保证金充值
    ];
    return "D" . $recharge_type[$type] . date('YmdHis') . mt_rand(10, 99) . $dealer_id;
}

/**
 * 系统公共库文件
 * 主要定义系统公共函数库
 */
/*
 * 格式化金钱格式（传入数字，大于万的保留两位小数，小于万的不保留小数）
 * @param float $money 金额
 * @return float
 * */
function format_money($money, $flag = true)
{
    if ($money <= 0)
        return 0;
    switch ($money) {
        case $money < 10000:
            $money = sprintf("%01.2d", $money);
            break;
        case $money >= 10000:
            if ($flag == true) {
                $money = sprintf("%01.2f", $money / 10000) . '<i>万</i>';
            } else {
                $money = sprintf("%01.2f", $money / 10000) * 10000 . '<i>元</i>';
            }
            break;
        default:
            break;
    }
    return $money;
}

/**
 * 格式化行驶里程 不足100按100公里算，单位为万公里保留小数点后两位
 *
 * @param $mileage
 *
 * @return int
 */
function formatMileage($mileage)
{
    if ($mileage <= 0) {
        $mileage = 0;
    } elseif ($mileage < 100) {
        $mileage = 0.01;
    } else {
        $mileage = sprintf("%01.2f", $mileage / 10000);
    }
    return $mileage;
}

function convert_mileage($n = 0)
{
    $a = explode('.', $n / 10000);
    $m = substr(str_pad($a[1], 3, 0), -1);
    if ($m > 0) {
        $prefix = strstr($n / 10000, '.', true);
        $suffix = substr(str_replace('.', '', strstr($n / 10000, '.')), 0, 2) / 100 + 0.01;
        $i = floatval($prefix + $suffix);
    } else {
        $i = $n / 10000;
    }
    return $i;

}

/**
 * 检测用户是否登录
 *
 * @return integer 0-未登录，大于0-当前登录用户ID
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function is_login()
{
    //选择品牌，车系，车型的公用js不判断登录
    if (CONTROLLER_NAME == 'Trade') {
        if (ACTION_NAME == 'brands_orderby_py' or ACTION_NAME == 'series' or ACTION_NAME == 'models') {
            return;
        }
    }

    if (CONTROLLER_NAME == 'Car' && ACTION_NAME == 'dm_pic_to_json') {
        return;
    }

    //用户是否处于登录状态
    $flag = true;
    $user_info = json_decode(session('user_info'), true);
    if (empty($user_info)) {
        $flag = false;
    }

    //路由
    if (MODULE_NAME == 'AuctionFront' && CONTROLLER_NAME == 'Index') {//登录页面，不跳转
        return;
    }

    /*if (MODULE_NAME == 'AuctionSite') {//访问主站页面不需要登录,Owner控制器内做登录验证
        return;
    }*/

    if (!$flag) {
        $url = WEB_URL;
        switch (MODULE_NAME) {
            case 'AuctionSite'://车主登录
                $url .= 'Auth/login';
                break;
            case 'AuctionFront'://车商登录
                $url .= '';
                break;
        }
        redirect($url, '2', '请先登录');
//        redirect('/Auth/login', '2', '请先登录');
    }
}

/**
 * 生成短链接
 *
 * @param string $long_url长url
 * @param string $name 键名
 *
 * @return mixed
 */
function get_short_url($long_url, $name)
{
    $mem = new \AuctionCore\Common\PhpMemcache();
    $short_url = $mem->get('short_url_' . $name);
    if (empty($short_url)) {
        //新浪短链接api
        $sina_api_url = 'http://api.t.sina.com.cn/short_url/shorten.json?source=374767190&url_long=' . $long_url;
        $sina_data = curl($sina_api_url);
        $sina_json_data = json_decode($sina_data, JSON_UNESCAPED_UNICODE);
        $short_url = $sina_json_data[0]['url_short'];
        //记录短链接
        $mem->set('short_url_' . $name, $short_url, 604800);//7 days
    }
    return $short_url;
}

/**
 * 数据采集
 *
 * @param $url
 *
 * @return mixed
 */
function curl($url)
{
    //初始化
    $ch = curl_init();

    //设置选项，包括URL
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_FAILONERROR, true);
    //执行并获取HTML文档内容
    $output = curl_exec($ch);

    //释放curl句柄
    curl_close($ch);

    return $output;
}

/*
 *
 * 计算时分秒
 * @param int $second 时间戳片段（秒）
 * @return array
 */

function format_second($second)
{
    $time = [];
    if ($second <= 0) {
        return ['h' => 0, 'i' => 0, 's' => 0];
    }
    if ($second < 60) {
        $time['h'] = 0;
        $time['i'] = 0;
        $time['s'] = $second;
    } elseif ($second >= 60 && $second < 3600) {
        $time['h'] = 0;
        $time['i'] = floor($second / 60);
        $time['s'] = $second % 60;
    } elseif ($second >= 3600) {
        $time['h'] = floor($second / 3600); //<60分
        $time['i'] = floor(($second % 3600) / 60);
        $time['s'] = ($second % 3600) % 60;
    }
    return $time;
}

/*
 * 检测管理员（员工）是否登录
 * */

function is_login_admin()
{
    $user = session('admin_info');
    if (empty($user)) {
        //return 0;
    } else {
        //return session('user_auth_sign') == data_auth_sign($user) ? $user['uid'] : 0;
    }
}

/*
 * 数字转为大写
 * */

function numToUpper($n)
{
    $arr = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十'];
    return $arr[$n];
}

/*
 * 获取文件名后缀
 * */

function get_extension($file)
{
    return pathinfo($file, PATHINFO_EXTENSION);
}


function get_filename($file)
{
    return pathinfo($file, PATHINFO_FILENAME);
}

/*
 * 生成密码
 * */

function encrptPass($pass)
{
    return md5($pass);
}

/*
 * 生面唯一ID
 * */

function genId()
{
    return str_replace(".", "", uniqid('', true));
}

/*
 * 生成唯一文件名
 * */

function create_uuid($prefix = "")
{    //可以指定前缀
    $str = md5(uniqid(mt_rand(), true));
    $uuid = substr($str, 0, 8) . '-';
    $uuid .= substr($str, 8, 4) . '-';
    $uuid .= substr($str, 12, 4) . '-';
    $uuid .= substr($str, 16, 4) . '-';
    $uuid .= substr($str, 20, 12);
    return $prefix . $uuid;
}

/* 隐藏手机号中间几位
 * @param string $mobile 手机号码
 * @param int $num 屏蔽长度
 * @return
 * */

function showHideMobile($mobile, $num = 4)
{
    if (!$mobile) {
        return "185****" . rand(1000, 9999);
    }
    if ($num == 4) {
        return substr($mobile, 0, 3) . "****" . substr($mobile, -4);
    }
}

/**
 * 系统加密方法
 *
 * @param string $data   要加密的字符串
 * @param string $key    加密密钥
 * @param int    $expire 过期时间 单位 秒
 *
 * @return string
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function think_encrypt($data, $key = '', $expire = 0)
{
    $key = md5(empty($key) ? C('DATA_AUTH_KEY') : $key);
    $data = base64_encode($data);
    $x = 0;
    $len = strlen($data);
    $l = strlen($key);
    $char = '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l)
            $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    $str = sprintf('%010d', $expire ? $expire + time() : 0);

    for ($i = 0; $i < $len; $i++) {
        $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1))) % 256);
    }
    return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($str));
}

/**
 * 系统解密方法
 *
 * @param  string $data 要解密的字符串 （必须是think_encrypt方法加密的字符串）
 * @param  string $key  加密密钥
 *
 * @return string
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function think_decrypt($data, $key = '')
{
    $key = md5(empty($key) ? C('DATA_AUTH_KEY') : $key);
    $data = str_replace(['-', '_'], ['+', '/'], $data);
    $mod4 = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    $data = base64_decode($data);
    $expire = substr($data, 0, 10);
    $data = substr($data, 10);

    if ($expire > 0 && $expire < time()) {
        return '';
    }
    $x = 0;
    $len = strlen($data);
    $l = strlen($key);
    $char = $str = '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l)
            $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    for ($i = 0; $i < $len; $i++) {
        if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))) {
            $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
        } else {
            $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
        }
    }
    return base64_decode($str);
}

/* ------------------------------------以下函数，系统尚未采用-------------------------------------- */

/**
 * 检测当前用户是否为管理员
 *
 * @return boolean true-管理员，false-非管理员
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function is_administrator($uid = null)
{
    $uid = is_null($uid) ? is_login() : $uid;
    return $uid && (intval($uid) === C('USER_ADMINISTRATOR'));
}

//读取用户存储信息
function getUsersSession($key = '')
{
    $user = session('user_info');
    if (empty($user)) {
        if ($key) {
            return '';
        } else
            return [];
    } else {
        if ($key) {
            return $user[$key];
        } else
            return $user;
    }
}

//写入到用户存储信息
function inputUsersSession($key, $value = NULL)
{
    $user = session('user_auth');
    $user[$key] = $value;
    session('user_auth', $user);
    session('user_auth_sign', data_auth_sign($user));
}

/**
 * 字符串转换为数组，主要用于把分隔符调整到第二个参数
 *
 * @param  string $str  要分割的字符串
 * @param  string $glue 分割符
 *
 * @return array
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function str2arr($str, $glue = ',')
{
    return explode($glue, $str);
}

/**
 * 数组转换为字符串，主要用于把分隔符调整到第二个参数
 *
 * @param  array  $arr  要连接的数组
 * @param  string $glue 分割符
 *
 * @return string
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function arr2str($arr, $glue = ',')
{
    return implode($glue, $arr);
}

/**
 * 字符串截取，支持中文和其他编码
 *
 * @static
 * @access public
 *
 * @param string $str     需要转换的字符串
 * @param string $start   开始位置
 * @param string $length  截取长度
 * @param string $charset 编码格式
 * @param string $suffix  截断显示字符
 *
 * @return string
 */
function msubstr($str, $start, $length, $charset = "utf-8", $suffix = true)
{
    if (function_exists("mb_substr"))
        $slice = mb_substr($str, $start, $length, $charset);
    elseif (function_exists('iconv_substr')) {
        $slice = iconv_substr($str, $start, $length, $charset);
        if (false === $slice) {
            $slice = '';
        }
    } else {
        $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        $slice = join("", array_slice($match[0], $start, $length));
    }
    return $suffix ? $slice . '...' : $slice;
}

/**
 * 数据签名认证
 *
 * @param  array $data 被认证的数据
 *
 * @return string       签名
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function data_auth_sign($data)
{
    //数据类型检测
    if (!is_array($data)) {
        $data = (array)$data;
    }
    ksort($data); //排序
    $code = http_build_query($data); //url编码并生成query字符串
    $sign = sha1($code); //生成签名
    return $sign;
}

/**
 * 对查询结果集进行排序
 *
 * @access public
 *
 * @param array  $list   查询结果
 * @param string $field  排序的字段名
 * @param array  $sortby 排序类型
 *                       asc正向排序 desc逆向排序 nat自然排序
 *
 * @return array
 */
function list_sort_by($list, $field, $sortby = 'asc')
{
    if (is_array($list)) {
        $refer = $resultSet = [];
        foreach ($list as $i => $data)
            $refer[$i] = &$data[$field];
        switch ($sortby) {
            case 'asc': // 正向排序
                asort($refer);
                break;
            case 'desc':// 逆向排序
                arsort($refer);
                break;
            case 'nat': // 自然排序
                natcasesort($refer);
                break;
        }
        foreach ($refer as $key => $val)
            $resultSet[] = &$list[$key];
        return $resultSet;
    }
    return false;
}

/**
 * 把返回的数据集转换成Tree
 *
 * @param array  $list  要转换的数据集
 * @param string $pid   parent标记字段
 * @param string $level level标记字段
 *
 * @return array
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root = 0)
{
    // 创建Tree
    $tree = [];
    if (is_array($list)) {
        // 创建基于主键的数组引用
        $refer = [];
        foreach ($list as $key => $data) {
            $refer[$data[$pk]] = &$list[$key];
        }
        foreach ($list as $key => $data) {
            // 判断是否存在parent
            $parentId = $data[$pid];
            if ($root == $parentId) {
                $tree[] = &$list[$key];
            } else {
                if (isset($refer[$parentId])) {
                    $parent = &$refer[$parentId];
                    $parent[$child][] = &$list[$key];
                }
            }
        }
    }
    return $tree;
}

/**
 * 将list_to_tree的树还原成列表
 *
 * @param  array  $tree  原来的树
 * @param  string $child 孩子节点的键
 * @param  string $order 排序显示的键，一般是主键 升序排列
 * @param  array  $list  过渡用的中间数组，
 *
 * @return array        返回排过序的列表数组
 * @author yangweijie <yangweijiester@gmail.com>
 */
function tree_to_list($tree, $child = '_child', $order = 'id', &$list = [])
{
    if (is_array($tree)) {
        foreach ($tree as $key => $value) {
            $reffer = $value;
            if (isset($reffer[$child])) {
                unset($reffer[$child]);
                tree_to_list($value[$child], $child, $order, $list);
            }
            $list[] = $reffer;
        }
        $list = list_sort_by($list, $order, $sortby = 'asc');
    }
    return $list;
}

/**
 * 格式化字节大小
 *
 * @param  number $size      字节数
 * @param  string $delimiter 数字和单位分隔符
 *
 * @return string            格式化后的带单位的大小
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function format_bytes($size, $delimiter = '')
{
    $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
    for ($i = 0; $size >= 1024 && $i < 5; $i++)
        $size /= 1024;
    return round($size, 2) . $delimiter . $units[$i];
}

/**
 * 设置跳转页面URL
 * 使用函数再次封装，方便以后选择不同的存储方式（目前使用cookie存储）
 *
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function set_redirect_url($url)
{
    cookie('redirect_url', $url);
}

/**
 * 获取跳转页面URL
 *
 * @return string 跳转页URL
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function get_redirect_url()
{
    $url = cookie('redirect_url');
    return empty($url) ? __APP__ : $url;
}

/**
 * 处理插件钩子
 *
 * @param string $hook   钩子名称
 * @param mixed  $params 传入参数
 *
 * @return void
 */
function hook($hook, $params = [])
{
    \Think\Hook::listen($hook, $params);
}

/**
 * 获取插件类的类名
 *
 * @param strng $name 插件名
 */
function get_addon_class($name)
{
    $class = "Addons\\{$name}\\{$name}Addon";
    return $class;
}

/**
 * 获取插件类的配置文件数组
 *
 * @param string $name 插件名
 */
function get_addon_config($name)
{
    $class = get_addon_class($name);
    if (class_exists($class)) {
        $addon = new $class();
        return $addon->getConfig();
    } else {
        return [];
    }
}

/**
 * 插件显示内容里生成访问插件的url
 *
 * @param string $url   url
 * @param array  $param 参数
 *
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function addons_url($url, $param = [])
{
    $url = parse_url($url);
    $case = C('URL_CASE_INSENSITIVE');
    $addons = $case ? parse_name($url['scheme']) : $url['scheme'];
    $controller = $case ? parse_name($url['host']) : $url['host'];
    $action = trim($case ? strtolower($url['path']) : $url['path'], '/');

    /* 解析URL带的参数 */
    if (isset($url['query'])) {
        parse_str($url['query'], $query);
        $param = array_merge($query, $param);
    }

    /* 基础参数 */
    $params = [
        '_addons'     => $addons,
        '_controller' => $controller,
        '_action'     => $action,
    ];
    $params = array_merge($params, $param); //添加额外参数

    return U('Addons/execute', $params);
}

/**
 * 时间戳格式化
 *
 * @param int $time
 *
 * @return string 完整的时间显示
 * @author huajie <banhuajie@163.com>
 */
function time_format($time = NULL, $format = 'Y-m-d H:i')
{
    $time = $time === NULL ? NOW_TIME : intval($time);
    return date($format, $time);
}

/**
 * 根据用户ID获取用户名
 *
 * @param  integer $uid 用户ID
 *
 * @return string       用户名
 */
function get_username($uid = 0)
{
    static $list;
    if (!($uid && is_numeric($uid))) { //获取当前登录用户名
        return session('user_auth.username');
    }

    /* 获取缓存数据 */
    if (empty($list)) {
        $list = S('sys_active_user_list');
    }

    /* 查找用户信息 */
    $key = "u{$uid}";
    if (isset($list[$key])) { //已缓存，直接使用
        $name = $list[$key];
    } else { //调用接口获取用户信息
        $User = new AuctionCore\AuctionCheckApi\UserApi();
        $info = $User->info($uid);
        if ($info && isset($info[1])) {
            $name = $list[$key] = $info[1];
            /* 缓存用户 */
            $count = count($list);
            $max = C('USER_MAX_CACHE');
            while ($count-- > $max) {
                array_shift($list);
            }
            S('sys_active_user_list', $list);
        } else {
            $name = '';
        }
    }
    return $name;
}

/**
 * 根据用户ID获取用户昵称
 *
 * @param  integer $uid 用户ID
 *
 * @return string       用户昵称
 */
function get_nickname($uid = 0)
{
    static $list;
    if (!($uid && is_numeric($uid))) { //获取当前登录用户名
        return session('user_auth.username');
    }

    /* 获取缓存数据 */
    if (empty($list)) {
        $list = S('sys_user_nickname_list');
    }

    /* 查找用户信息 */
    $key = "u{$uid}";
    if (isset($list[$key])) { //已缓存，直接使用
        $name = $list[$key];
    } else { //调用接口获取用户信息
        $info = M('Member')->field('nickname')->find($uid);
        if ($info !== false && $info['nickname']) {
            $nickname = $info['nickname'];
            $name = $list[$key] = $nickname;
            /* 缓存用户 */
            $count = count($list);
            $max = C('USER_MAX_CACHE');
            while ($count-- > $max) {
                array_shift($list);
            }
            S('sys_user_nickname_list', $list);
        } else {
            $name = '';
        }
    }
    return $name;
}

/**
 * 获取分类信息并缓存分类
 *
 * @param  integer $id    分类ID
 * @param  string  $field 要获取的字段名
 *
 * @return string         分类信息
 */
function get_category($id, $field = null)
{
    static $list;

    /* 非法分类ID */
    if (empty($id) || !is_numeric($id)) {
        return '';
    }

    /* 读取缓存数据 */
    if (empty($list)) {
        $list = S('sys_category_list');
    }

    /* 获取分类名称 */
    if (!isset($list[$id])) {
        $cate = M('Category')->find($id);
        if (!$cate || 1 != $cate['status']) { //不存在分类，或分类被禁用
            return '';
        }
        $list[$id] = $cate;
        S('sys_category_list', $list); //更新缓存
    }
    return is_null($field) ? $list[$id] : $list[$id][$field];
}

/* 根据ID获取分类标识 */

function get_category_name($id)
{
    return get_category($id, 'name');
}

/* 根据ID获取分类名称 */

function get_category_title($id)
{
    return get_category($id, 'title');
}

/**
 * 获取顶级模型信息
 */
function get_top_model($model_id = null)
{
    $map = ['status' => 1, 'extend' => 0];
    if (!is_null($model_id)) {
        $map['id'] = ['neq', $model_id];
    }
    $model = M('Model')->where($map)->field(true)->select();
    $list = [];
    foreach ($model as $value) {
        $list[$value['id']] = $value;
    }
    return $list;
}

/**
 * 获取文档模型信息
 *
 * @param  integer $id    模型ID
 * @param  string  $field 模型字段
 *
 * @return array
 */
function get_document_model($id = null, $field = null)
{
    static $list;

    /* 非法分类ID */
    if (!(is_numeric($id) || is_null($id))) {
        return '';
    }

    /* 读取缓存数据 */
    if (empty($list)) {
        $list = S('DOCUMENT_MODEL_LIST');
    }

    /* 获取模型名称 */
    if (empty($list)) {
        $map = ['status' => 1, 'extend' => 1];
        $model = M('Model')->where($map)->field(true)->select();
        foreach ($model as $value) {
            $list[$value['id']] = $value;
        }
        S('DOCUMENT_MODEL_LIST', $list); //更新缓存
    }

    /* 根据条件返回数据 */
    if (is_null($id)) {
        return $list;
    } elseif (is_null($field)) {
        return $list[$id];
    } else {
        return $list[$id][$field];
    }
}

/**
 * 记录行为日志，并执行该行为的规则
 *
 * @param string $action    行为标识
 * @param string $model     触发行为的模型名
 * @param int    $record_id 触发行为的记录id
 * @param int    $user_id   执行行为的用户id
 *
 * @return boolean
 * @author huajie <banhuajie@163.com>
 */
function action_log($action = null, $model = null, $record_id = null, $user_id = null)
{

    //参数检查
    if (empty($action) || empty($model) || empty($record_id)) {
        return '参数不能为空';
    }
    if (empty($user_id)) {
        $user_id = is_login();
    }

    //查询行为,判断是否执行
    $action_info = M('Action')->getByName($action);
    if ($action_info['status'] != 1) {
        return '该行为被禁用或删除';
    }

    //插入行为日志
    $data['action_id'] = $action_info['id'];
    $data['user_id'] = $user_id;
    $data['action_ip'] = ip2long(get_client_ip());
    $data['model'] = $model;
    $data['record_id'] = $record_id;
    $data['create_time'] = NOW_TIME;

    //解析日志规则,生成日志备注
    if (!empty($action_info['log'])) {
        if (preg_match_all('/\[(\S+?)\]/', $action_info['log'], $match)) {
            $log['user'] = $user_id;
            $log['record'] = $record_id;
            $log['model'] = $model;
            $log['time'] = NOW_TIME;
            $log['data'] = ['user' => $user_id, 'model' => $model, 'record' => $record_id, 'time' => NOW_TIME];
            foreach ($match[1] as $value) {
                $param = explode('|', $value);
                if (isset($param[1])) {
                    $replace[] = call_user_func($param[1], $log[$param[0]]);
                } else {
                    $replace[] = $log[$param[0]];
                }
            }
            $data['remark'] = str_replace($match[0], $replace, $action_info['log']);
        } else {
            $data['remark'] = $action_info['log'];
        }
    } else {
        //未定义日志规则，记录操作url
        $data['remark'] = '操作url：' . $_SERVER['REQUEST_URI'];
    }

    M('ActionLog')->add($data);

    if (!empty($action_info['rule'])) {
        //解析行为
        $rules = parse_action($action, $user_id);

        //执行行为
        $res = execute_action($rules, $action_info['id'], $user_id);
    }
}

/**
 * 解析行为规则
 * 规则定义  table:$table|field:$field|condition:$condition|rule:$rule[|cycle:$cycle|max:$max][;......]
 * 规则字段解释：table->要操作的数据表，不需要加表前缀；
 *              field->要操作的字段；
 *              condition->操作的条件，目前支持字符串，默认变量{$self}为执行行为的用户
 *              rule->对字段进行的具体操作，目前支持四则混合运算，如：1+score*2/2-3
 *              cycle->执行周期，单位（小时），表示$cycle小时内最多执行$max次
 *              max->单个周期内的最大执行次数（$cycle和$max必须同时定义，否则无效）
 * 单个行为后可加 ； 连接其他规则
 *
 * @param string $action 行为id或者name
 * @param int    $self   替换规则里的变量为执行用户的id
 *
 * @return boolean|array: false解析出错 ， 成功返回规则数组
 * @author huajie <banhuajie@163.com>
 */
function parse_action($action, $self)
{
    if (empty($action)) {
        return false;
    }

    //参数支持id或者name
    if (is_numeric($action)) {
        $map = ['id' => $action];
    } else {
        $map = ['name' => $action];
    }

    //查询行为信息
    $info = M('Action')->where($map)->find();
    if (!$info || $info['status'] != 1) {
        return false;
    }

    //解析规则:table:$table|field:$field|condition:$condition|rule:$rule[|cycle:$cycle|max:$max][;......]
    $rules = $info['rule'];
    $rules = str_replace('{$self}', $self, $rules);
    $rules = explode(';', $rules);
    $return = [];
    foreach ($rules as $key => &$rule) {
        $rule = explode('|', $rule);
        foreach ($rule as $k => $fields) {
            $field = empty($fields) ? [] : explode(':', $fields);
            if (!empty($field)) {
                $return[$key][$field[0]] = $field[1];
            }
        }
        //cycle(检查周期)和max(周期内最大执行次数)必须同时存在，否则去掉这两个条件
        if (!array_key_exists('cycle', $return[$key]) || !array_key_exists('max', $return[$key])) {
            unset($return[$key]['cycle'], $return[$key]['max']);
        }
    }

    return $return;
}

/**
 * 执行行为
 *
 * @param array $rules     解析后的规则数组
 * @param int   $action_id 行为id
 * @param array $user_id   执行的用户id
 *
 * @return boolean false 失败 ， true 成功
 * @author huajie <banhuajie@163.com>
 */
function execute_action($rules = false, $action_id = null, $user_id = null)
{
    if (!$rules || empty($action_id) || empty($user_id)) {
        return false;
    }

    $return = true;
    foreach ($rules as $rule) {

        //检查执行周期
        $map = ['action_id' => $action_id, 'user_id' => $user_id];
        $map['create_time'] = ['gt', NOW_TIME - intval($rule['cycle']) * 3600];
        $exec_count = M('ActionLog')->where($map)->count();
        if ($exec_count > $rule['max']) {
            continue;
        }

        //执行数据库操作
        $Model = M(ucfirst($rule['table']));
        $field = $rule['field'];
        $res = $Model->where($rule['condition'])->setField($field, ['exp', $rule['rule']]);

        if (!$res) {
            $return = false;
        }
    }
    return $return;
}

//基于数组创建目录和文件
function create_dir_or_files($files)
{
    foreach ($files as $key => $value) {
        if (substr($value, -1) == '/') {
            mkdir($value);
        } else {
            @file_put_contents($value, '');
        }
    }
}

if (!function_exists('array_column')) {

    function array_column(array $input, $columnKey, $indexKey = null)
    {
        $result = [];
        if (null === $indexKey) {
            if (null === $columnKey) {
                $result = array_values($input);
            } else {
                foreach ($input as $row) {
                    $result[] = $row[$columnKey];
                }
            }
        } else {
            if (null === $columnKey) {
                foreach ($input as $row) {
                    $result[$row[$indexKey]] = $row;
                }
            } else {
                foreach ($input as $row) {
                    $result[$row[$indexKey]] = $row[$columnKey];
                }
            }
        }
        return $result;
    }

}

/**
 * 获取表名（不含表前缀）
 *
 * @param string $model_id
 *
 * @return string 表名
 * @author huajie <banhuajie@163.com>
 */
function get_table_name($model_id = null)
{
    if (empty($model_id)) {
        return false;
    }
    $Model = M('Model');
    $name = '';
    $info = $Model->getById($model_id);
    if ($info['extend'] != 0) {
        $name = $Model->getFieldById($info['extend'], 'name') . '_';
    }
    $name .= $info['name'];
    return $name;
}

/**
 * 获取属性信息并缓存
 *
 * @param  integer $id    属性ID
 * @param  string  $field 要获取的字段名
 *
 * @return string         属性信息
 */
function get_model_attribute($model_id, $group = true, $fields = true)
{
    static $list;

    /* 非法ID */
    if (empty($model_id) || !is_numeric($model_id)) {
        return '';
    }

    /* 获取属性 */
    if (!isset($list[$model_id])) {
        $map = ['model_id' => $model_id];
        $extend = M('Model')->getFieldById($model_id, 'extend');

        if ($extend) {
            $map = ['model_id' => ["in", [$model_id, $extend]]];
        }
        $info = M('Attribute')->where($map)->field($fields)->select();
        $list[$model_id] = $info;
    }

    $attr = [];
    if ($group) {
        foreach ($list[$model_id] as $value) {
            $attr[$value['id']] = $value;
        }
        $model = M("Model")->field("field_sort,attribute_list,attribute_alias")->find($model_id);
        $attribute = explode(",", $model['attribute_list']);
        if (empty($model['field_sort'])) { //未排序
            $group = [1 => array_merge($attr)];
        } else {
            $group = json_decode($model['field_sort'], true);

            $keys = array_keys($group);
            foreach ($group as &$value) {
                foreach ($value as $key => $val) {
                    $value[$key] = $attr[$val];
                    unset($attr[$val]);
                }
            }

            if (!empty($attr)) {
                foreach ($attr as $key => $val) {
                    if (!in_array($val['id'], $attribute)) {
                        unset($attr[$key]);
                    }
                }
                $group[$keys[0]] = array_merge($group[$keys[0]], $attr);
            }
        }
        if (!empty($model['attribute_alias'])) {
            $alias = preg_split('/[;\r\n]+/s', $model['attribute_alias']);
            $fields = [];
            foreach ($alias as &$value) {
                $val = explode(':', $value);
                $fields[$val[0]] = $val[1];
            }
            foreach ($group as &$value) {
                foreach ($value as $key => $val) {
                    if (!empty($fields[$val['name']])) {
                        $value[$key]['title'] = $fields[$val['name']];
                    }
                }
            }
        }
        $attr = $group;
    } else {
        foreach ($list[$model_id] as $value) {
            $attr[$value['name']] = $value;
        }
    }
    return $attr;
}

/**
 * 调用系统的API接口方法（静态方法）
 * api('User/getName','id=5'); 调用公共模块的User接口的getName方法
 * api('Admin/User/getName','id=5');  调用Admin模块的User接口
 *
 * @param  string       $name 格式 [模块名]/接口名/方法名
 * @param  array|string $vars 参数
 */
function api($name, $vars = [])
{
    $array = explode('/', $name);
    $method = array_pop($array);
    $classname = array_pop($array);
    $module = $array ? array_pop($array) : 'Common';
    $callback = $module . '\\AuctionCheckApi\\' . $classname . 'Api::' . $method;
    if (is_string($vars)) {
        parse_str($vars, $vars);
    }
    return call_user_func_array($callback, $vars);
}

/**
 * 根据条件字段获取指定表的数据
 *
 * @param mixed  $value     条件，可用常量或者数组
 * @param string $condition 条件字段
 * @param string $field     需要返回的字段，不传则返回整个数据
 * @param string $table     需要查询的表
 *
 * @author huajie <banhuajie@163.com>
 */
function get_table_field($value = null, $condition = 'id', $field = null, $table = null)
{
    if (empty($value) || empty($table)) {
        return false;
    }
    //拼接参数
    $map[$condition] = $value;
    $info = M(ucfirst($table))->where($map);
    if (empty($field)) {
        $info = $info->field(true)->find();
    } else {
        $info = $info->getField($field);
    }
    return $info;
}

/**
 * 获取链接信息
 *
 * @param int    $link_id
 * @param string $field
 *
 * @return 完整的链接信息或者某一字段
 * @author huajie <banhuajie@163.com>
 */
function get_link($link_id = null, $field = 'url')
{
    $link = '';
    if (empty($link_id)) {
        return $link;
    }
    $link = M('Url')->getById($link_id);
    if (empty($field)) {
        return $link;
    } else {
        return $link[$field];
    }
}

/**
 * 获取文档封面图片
 *
 * @param int    $cover_id
 * @param string $field
 *
 * @return 完整的数据  或者  指定的$field字段值
 * @author huajie <banhuajie@163.com>
 */
function get_cover($cover_id, $field = null)
{
    if (empty($cover_id)) {
        return false;
    }
    $picture = M('Picture')->where(['status' => 1])->getById($cover_id);
    if ($field == 'path') {
        if (!empty($picture['url'])) {
            $picture['path'] = $picture['url'];
        } else {
            $picture['path'] = __ROOT__ . $picture['path'];
        }
    }
    return empty($field) ? $picture : $picture[$field];
}

/**
 * 检查$pos(推荐位的值)是否包含指定推荐位$contain
 *
 * @param number $pos     推荐位的值
 * @param number $contain 指定推荐位
 *
 * @return boolean true 包含 ， false 不包含
 * @author huajie <banhuajie@163.com>
 */
function check_document_position($pos = 0, $contain = 0)
{
    if (empty($pos) || empty($contain)) {
        return false;
    }

    //将两个参数进行按位与运算，不为0则表示$contain属于$pos
    $res = $pos & $contain;
    if ($res !== 0) {
        return true;
    } else {
        return false;
    }
}

/**
 * 验证分类是否允许发布内容
 *
 * @param  integer $id 分类ID
 *
 * @return boolean     true-允许发布内容，false-不允许发布内容
 */
function check_category($id)
{
    if (is_array($id)) {
        $id['type'] = !empty($id['type']) ? $id['type'] : 2;
        $type = get_category($id['category_id'], 'type');
        $type = explode(",", $type);
        return in_array($id['type'], $type);
    } else {
        $publish = get_category($id, 'allow_publish');
        return $publish ? true : false;
    }
}

function isPhone($phone)
{

    return strlen($phone) > 6 && preg_match("/^(010|02\d{1}|0[3-9]\d{2})-\d{7,9}(-\d+)?$/", $phone);
}

function isEmail($email)
{

    return strlen($email) > 6 && preg_match("/^[\w\-\.]+@[\w\-]+(\.\w+)+$/", $email);
}

function isMobile($mobile)
{

    return strlen($mobile) == 11 && preg_match("/^1\d{10}$/", $mobile);
}

function isDecimals($decimals)
{
    ///^(\d+)\.(\d+)/$
    return preg_match("/^\d{1,6}\.{0,1}\d{0,2}$/", $decimals);
}

/**
 * 验证时间格式 YY-mm-dd H:i:s
 */
function validateDatetime($datetime)
{
    $reg_match = "/^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/";
    return preg_match($reg_match, $datetime);
}

/**
 * 验证手机号
 *
 * @param string $phone
 *
 * @return boolean $type
 */
function validatePhone($phone)
{
    if (!is_numeric($phone)) {
        return false;
    }
    return strlen($phone) == 11 && preg_match("/^13[0-9]{9}$|14[0-9]{9}|15[0-9]{9}$|17[0-9]{9}$|18[0-9]{9}$/", $phone);
}

/**
 * 生成手机验证码
 *
 * @param type $length
 *
 * @return type
 */
function generateCode($length = 6)
{
    return str_pad(mt_rand(0, pow(10, $length) - 1), $length, '0', STR_PAD_LEFT);
}

/**
 * 验证手机验证码
 * $param type int $auth_code 手机验证码
 */
function validateAuthCode($auth_code)
{
    if (!is_numeric($auth_code)) {
        return false;
    }
    return strlen($auth_code) == 6 && preg_match("/^[0-9]{6}$/", $auth_code);
}

/**
 * 验证日期格式 yyyy-MM (/^(\d{4})-(\d{2})-(\d{2})$/)
 *
 * @param date $date
 *
 * @return int
 */
function validateDate($date)
{
    return preg_match("/^(\d{4})-(\d{2})$/", $date);
}

//根据身份证号码获取用户的性别与出生年月
function getUsersDataByIdCard($cid)
{
    $data = [];
    if (strlen($cid) == 18) {
        $data['year'] = substr($cid, 6, 4);
        $data['month'] = intval(substr($cid, 10, 2));
        $data['day'] = intval(substr($cid, 12, 2));
        if (substr($cid, -2, 1) % 2) {
            $data['sex'] = 1;
        } else
            $data['sex'] = 2;
    } else if (strlen($cid) == 15) {
        $data['year'] = '19' . substr($cid, 6, 2);
        $data['month'] = intval(substr($cid, 8, 2));
        $data['day'] = intval(substr($cid, 10, 2));
        if (substr($cid, -1, 1) % 2) {
            $data['sex'] = 1;
        } else
            $data['sex'] = 2;
    }
    return $data;
}

//检查身份证号
function isIdcard($id_card)
{
    if (strlen($id_card) == 18) {
        return idcard_checksum18($id_card);
    } elseif ((strlen($id_card) == 15)) {
        $id_card = idcard_15to18($id_card);
        return idcard_checksum18($id_card);
    } else {
        return false;
    }
}

// 计算身份证校验码，根据国家标准GB 11643-1999
function idcard_verify_number($idcard_base)
{
    if (strlen($idcard_base) != 17) {
        return false;
    }
    //加权因子
    $factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
    //校验码对应值
    $verify_number_list = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
    $checksum = 0;
    for ($i = 0; $i < strlen($idcard_base); $i++) {
        $checksum += substr($idcard_base, $i, 1) * $factor[$i];
    }
    $mod = $checksum % 11;
    $verify_number = $verify_number_list[$mod];
    return $verify_number;
}

// 将15位身份证升级到18位
function idcard_15to18($idcard)
{
    if (strlen($idcard) != 15) {
        return false;
    } else {
        // 如果身份证顺序码是996 997 998 999，这些是为百岁以上老人的特殊编码
        if (array_search(substr($idcard, 12, 3), ['996', '997', '998', '999']) !== false) {
            $idcard = substr($idcard, 0, 6) . '18' . substr($idcard, 6, 9);
        } else {
            $idcard = substr($idcard, 0, 6) . '19' . substr($idcard, 6, 9);
        }
    }
    $idcard = $idcard . idcard_verify_number($idcard);
    return $idcard;
}

// 18位身份证校验码有效性检查
function idcard_checksum18($idcard)
{
    if (strlen($idcard) != 18) {
        return false;
    }
    $idcard_base = substr($idcard, 0, 17);
    if (idcard_verify_number($idcard_base) != strtoupper(substr($idcard, 17, 1))) {
        return false;
    } else {
        return true;
    }
}

/*
 * 身份证15位编码规则：dddddd yymmdd xx p
 * dddddd：6位地区编码
 * yymmdd: 出生年(两位年)月日，如：910215
 * xx: 顺序编码，系统产生，无法确定
 * p: 性别，奇数为男，偶数为女
 *
 * 身份证18位编码规则：dddddd yyyymmdd xxx y
 * dddddd：6位地区编码
 * yyyymmdd: 出生年(四位年)月日，如：19910215
 * xxx：顺序编码，系统产生，无法确定，奇数为男，偶数为女
 * y: 校验码，该位数值可通过前17位计算获得
 *
 * 前17位号码加权因子为 Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ]
 * 验证位 Y = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ]
 * 如果验证码恰好是10，为了保证身份证是十八位，那么第十八位将用X来代替
 * 校验位计算公式：Y_P = mod( ∑(Ai×Wi),11 )
 * i为身份证号码1...17 位; Y_P为校验码Y所在校验码数组位置
 */

function validateIdCard($idCard)
{
    //15位和18位身份证号码的正则表达式
    $regIdCard = "/^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/";
    //如果通过该验证，说明身份证格式正确，但准确性还需计算
    if (preg_match($regIdCard, $idCard)) {
        if (strlen($idCard) == 15) {
            $idCard = getIDCard($idCard);
        }
        if (strlen($idCard) == 18) {
            $idCardWi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; //将前17位加权因子保存在数组里
            $idCardY = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2];   //这是除以11后，可能产生的11位余数、验证码，也保存成数组
            $idCardWiSum = 0;                               //用来保存前17位各自乖以加权因子后的总和
            for ($i = 0; $i < 17; $i++) {
                $idCardWiSum += substr($idCard, $i, 1) * $idCardWi[$i];
            }
            $idCardMod = $idCardWiSum % 11; //计算出校验码所在数组的位置
            $idCardLast = substr($idCard, 17); //得到最后一位身份证号码
            if ($idCardMod == 2) {//如果等于2，则说明校验码是10，身份证号码最后一位应该是X
                if ($idCardLast == "X" || $idCardLast == "x") {
                    return true;
                } else {
                    return false;
                }
            } else {
                //用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
                if ($idCardLast == $idCardY[$idCardMod]) {
                    return true;
                } else {
                    return false;
                }
            }
        }
    } else {
        return false;
    }
}

/**
 * 15位转18位
 *
 * @param type $idCard
 *
 * @return string
 */

/**
 * 15位转18位
 *
 * @param type $idCard
 *
 * @return string
 */
function getIDCard($idCard)
{
    // 若是15位，则转换成18位；否则直接返回ID
    if (15 == strlen($idCard)) {
        $W = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1];
        $A = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"];
        $s = 0;
        // 如果身份证顺序码是996 997 998 999，这些是为百岁以上老人的特殊编码 
        if (array_search(substr($idCard, 12, 3), ['996', '997', '998', '999']) !== false) {
            $idCard18 = substr($idCard, 0, 6) . '18' . substr($idCard, 6, 9);
        } else {
            $idCard18 = substr($idCard, 0, 6) . "19" . substr($idCard, 6, 9);
        }
        $idCard18_len = strlen($idCard18);
        for ($i = 0; $i < $idCard18_len; $i++) {
            $s = $s + substr($idCard18, $i, 1) * $W [$i];
        }
        $idCard18 .= $A [$s % 11];
        return $idCard18;
    } else {
        return $idCard;
    }
}

//add by  dxw    curl   post
function curlPost($url, $data, $decode = 1, $header = [])
{
    if (!$url) {
        return [];
    }
    if ($header) {
        if (is_array($header)) {
            $headerArr = $header;
        } else
            $headerArr = [
                "Connection:Keep-Alive",
                "Content-Type:text/plain;charset=utf-8",
            ];
    }
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    if ($header) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArr);
        curl_setopt($ch, CURLOPT_HEADER, 0);
    }
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_TIMEOUT, 20);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $res = curl_exec($ch);
    if (curl_errno($ch)) {
        \Think\Log::record(curl_error($ch) . ',错误码：' . curl_errno($ch) . ',time:' . date('Y-m-d H:i:s'));
        AuctionCore\System\AuctionException::make_throw('100080');
//        throw new Exception(curl_errno($ch));
    }
    curl_close($ch);
    if ($decode) {
        $res = json_decode($res, true);
    }
    return $res;
}

function curlGet($url, $decode = true)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    $json = curl_exec($ch);
    if (curl_errno($ch)) {
        \Think\Log::record(curl_error($ch) . ',错误码：' . curl_errno($ch) . ',time:' . date('Y-m-d H:i:s'));
        AuctionCore\System\AuctionException::make_throw('100080');
//        throw new Exception(curl_errno($ch));
    }
    curl_close($ch);
    return $decode ? json_decode($json, true) : $json;
}

//格式化金额    去除多余的位数
function dealDecimals($money = 0, $num = 2)
{
    $big = $num + 2;
    return sprintf("%." . $num . "f", substr(sprintf("%." . $big . "f", $money), 0, -$num));
}

//根据用户id获取用户名
function getUserNameByUid($uid, $type = 1)
{
    if (!$uid)
        return '';
    $info = getUsersInfo(['um.id' => $uid]);
    if ($type == 0) {
        return $info;
    } else if ($type == 2) {
        return $info['email'];
    }
    return $info['username'];
}

//根据条件获取用户列表
function getUsersListByCon($where = 1, $limit = 0, $size = 10, $order = "um.id desc")
{

    $fileds = "um.id,um.username,um.password,um.email,um.mobile,m.*  ";
    $list = M('ucenter_member')->table("as_ucenter_member um")
        ->join("as_member m on um.id = m.id")
        ->where($where)->field($fileds)->order($order)->limit($limit, $size)->select();

    return $list;
}

//日期格式化
function showDate($time = '', $rule = "Y-m-d H:i:s")
{
    if ($time) {
        return date($rule, $time);
    }
    return '';
}

//获取品牌列表
function getBrand($key = 'all')
{
    $brand = D('car_brand')->field('`brand_id`,`first_char`,`brand_name`')->select();
    return $brand;
}

//根据id获取品牌
function getBrandById($id, $key = '')
{
    return [];
}

//根据关键词查找品牌
function getBrandIdByName($key = '')
{
    return [];
}

//会员类型
function getUserType($key = 'all')
{
    $array = [
        '0' => "个人",
        '1' => "企业",
    ];
    if ($key == "all") {
        return $array;
    } else
        return $array[$key];
}

//定义产生的会员halt
function getUserCode($num = 6)
{
    $str = '';
    $arr = range("0", "9") + range("a", "z");
    for ($i = 0; $i < $num; $i++) {
        $str .= $arr[array_rand($arr)];
    }
    return $str;
}

//获取年
function getYear($start = 1960, $end = '', $order = 0)
{
    if (!$end) {
        $end = date("Y");
    }
    $year = [];
    if ($order == 1) {
        for ($i = $end; $i >= $start; $i--) {
            $year[] = $i;
        }
    } else {
        for ($i = $start; $i <= $end; $i++) {
            $year[] = $i;
        }
    }

    return $year;
}

//获取年月日
function getYMD($start = '', $stop = '')
{
    $array = [];
    if (!$start)
        $start = '1960';
    if (!$stop)
        $stop = date("Y");
    for ($i = $start; $i <= $stop; $i++) {
        $array['1'][$i] = $i;
    }
    for ($i = 1; $i < 13; $i++) {
        $array['2'][$i] = $i < 10 ? "0" . $i : $i;
    }
    for ($i = 1; $i < 32; $i++) {
        $array['3'][$i] = $i < 10 ? "0" . $i : $i;
    }
    return $array;
}

//输出日期
function showDay($time, $rule = 'Y-m-d H:i:s')
{
    if (!$time)
        return;
    return date($rule, $time);
}

//输出性别
function showSex($sex)
{
    $array = [
        1 => "男",
        2 => "女",
        0 => "未知"
    ];
    if (!$array[$sex])
        return "未知";
    return $array[$sex];
}

/* * ********
 * 发送邮件 *
 * ******** */

function SendMail($address, $title, $message, $configarr = '')
{
    if (!$configarr) {
        //$configarr = require(DATA_PATH.'webEmail.php');
    }

    $configarr = [
        'send_name'     => C("EMAIL_NAME"),
        'send_pwd'      => C("EMAIL_PASSWORD"),
        'send_address'  => C("EMAIL_ADDRESS"),
        'send_smtp'     => C("EMAIL_SMTP"),
        'reply_name'    => C("EMAIL_NAME"),
        'reply_address' => C("EMAIL_ADDRESS"),
    ];

    if (!$configarr || !$address || !$title || !$message) {
        return -1;
    }

    require_once(DATA_PATH . 'PHPMailer/class.phpmailer.php');

    $mail = new PHPMailer();
    // 设置PHPMailer使用SMTP服务器发送Email
    $mail->IsSMTP();

    $mail->SMTPDebug = 1; // 关闭SMTP调试功能
    // 设置邮件的字符编码，若不指定，则为'UTF-8'
    $mail->CharSet = 'UTF-8';

    // 添加收件人地址，可以多次使用来添加多个收件人
    $mail->AddAddress($address);

    // 设置邮件正文
    $mail->Body = $message;

    // 设置邮件头的From字段。
    $mail->From = $configarr['send_address'];

    // 设置发件人名字
    $mail->FromName = $configarr['send_name'];

    // 设置邮件标题
    $mail->Subject = $title;

    // 设置SMTP服务器。
    $mail->Host = $configarr['send_smtp'];

    // 设置为“需要验证”
    $mail->SMTPAuth = true;

    //$mail->Port = 465;
    // 设置用户名和密码。
    $mail->Username = $configarr['send_address'];
    $mail->Password = $configarr['send_pwd'];

    //回复
    $mail->AddReplyTo($configarr['reply_address'], $configarr['reply_name']);
    // 发送 HTML邮件
    $mail->IsHTML(true);

    // 发送邮件。
    $rs = $mail->Send();
    if (!$rs) {
        //echo $mail->ErrorInfo;exit;
        //echo 'Mailer Error: ' . $mail->ErrorInfo;
        //exit;
    }
    return $rs;
}

//添加操作日志
function addUsersOptLog($type = "100", $memo = "unknow", $mod = 'Home', $ext = [])
{
    if ($mod == 'Admin') {
        $uid = $_SESSION['admin_id'];
        $username = $_SESSION['admin_username'];
    } else {
        $uid = $_SESSION['uid'];
        $username = $_SESSION['username'];
    }
    $time = time();
    $ip = getIp();
    $data = [
        'type'         => $type,
        'uid'          => $uid,
        'username'     => $username,
        'mod'          => $mod,
        'memo'         => $memo,
        'addtime'      => $time,
        'ip'           => $ip,
        'for_uid'      => $ext[for_uid],
        'for_username' => $ext[for_username],
    ];
    $rs = M("opt_log")->add($data);

    if ($rs) {
        return true;
    } else
        return false;
}

//格式化动态
function getRuleFeed($content, $time = '', $title = '帖子')
{

    if (!$content) {
        return $content;
    }

    $content = str_replace("{title}", $title, $content);
    $ctime = '';
    if ($time) {
        $ctime = getLongTimeSpace($time);
    }

    $content = str_replace("{time}", $ctime, $content);
    return $content;
}

//根据汉字获取每个字母的首字母
function getFirstLetter($str)
{
    $fchar = ord($str{0});
    if ($fchar >= ord("A") and $fchar <= ord("z"))
        return strtoupper($str{0});
    $s1 = iconv("UTF-8", "gb2312", $str);
    $s2 = iconv("gb2312", "UTF-8", $s1);
    if ($s2 == $str) {
        $s = $s1;
    } else {
        $s = $str;
    }
    $asc = ord($s{0}) * 256 + ord($s{1}) - 65536;
    if ($asc >= -20319 and $asc <= -20284)
        return "a";
    if ($asc >= -20283 and $asc <= -19776)
        return "b";
    if ($asc >= -19775 and $asc <= -19219)
        return "c";
    if ($asc >= -19218 and $asc <= -18711)
        return "d";
    if ($asc >= -18710 and $asc <= -18527)
        return "e";
    if ($asc >= -18526 and $asc <= -18240)
        return "f";
    if ($asc >= -18239 and $asc <= -17923)
        return "g";
    if ($asc >= -17922 and $asc <= -17418)
        return "i";
    if ($asc >= -17417 and $asc <= -16475)
        return "j";
    if ($asc >= -16474 and $asc <= -16213)
        return "k";
    if ($asc >= -16212 and $asc <= -15641)
        return "l";
    if ($asc >= -15640 and $asc <= -15166)
        return "m";
    if ($asc >= -15165 and $asc <= -14923)
        return "n";
    if ($asc >= -14922 and $asc <= -14915)
        return "o";
    if ($asc >= -14914 and $asc <= -14631)
        return "p";
    if ($asc >= -14630 and $asc <= -14150)
        return "q";
    if ($asc >= -14149 and $asc <= -14091)
        return "r";
    if ($asc >= -14090 and $asc <= -13319)
        return "s";
    if ($asc >= -13318 and $asc <= -12839)
        return "t";
    if ($asc >= -12838 and $asc <= -12557)
        return "w";
    if ($asc >= -12556 and $asc <= -11848)
        return "x";
    if ($asc >= -11847 and $asc <= -11056)
        return "y";
    if ($asc >= -11055 and $asc <= -10247)
        return "z";
    return null;
}

function getFirstChar($zh)
{
    $ret = "";
    $s1 = iconv("UTF-8", "gb2312", $zh);
    $s2 = iconv("gb2312", "UTF-8", $s1);
    if ($s2 == $zh) {
        $zh = $s1;
    }
    for ($i = 0; $i < strlen($zh); $i++) {
        $s1 = substr($zh, $i, 1);
        $p = ord($s1);
        if ($p > 160) {
            $s2 = substr($zh, $i++, 2);
            $ret .= getFirstLetter($s2);
        } else {
            $ret .= $s1;
        }
    }
    return $ret;
}

//==================上传图  裁剪=============================

function cutZoomImages($new_pic)
{
    list($width, $height) = getimagesize($_POST["imageSource"]);
    $viewPortW = $_POST["viewPortW"];
    $viewPortH = $_POST["viewPortH"];
    $pWidth = $_POST["imageW"];
    $pHeight = $_POST["imageH"];
    $endexplode = explode(".", $_POST["imageSource"]);
    $ext = end($endexplode);
    $function = returnCorrectFunction($ext);
    $image = $function($_POST["imageSource"]);
    $width = imagesx($image);
    $height = imagesy($image);
    // Resample
    $image_p = imagecreatetruecolor($pWidth, $pHeight);
    setTransparency($image, $image_p, $ext);
    imagecopyresampled($image_p, $image, 0, 0, 0, 0, $pWidth, $pHeight, $width, $height);
    imagedestroy($image);
    $widthR = imagesx($image_p);
    $hegihtR = imagesy($image_p);

    $selectorX = $_POST["selectorX"];
    $selectorY = $_POST["selectorY"];

    if ($_POST["imageRotate"]) {
        $angle = 360 - $_POST["imageRotate"];
        $image_p = imagerotate($image_p, $angle, 0);

        $pWidth = imagesx($image_p);
        $pHeight = imagesy($image_p);

        //print $pWidth."---".$pHeight;

        $diffW = abs($pWidth - $widthR) / 2;
        $diffH = abs($pHeight - $hegihtR) / 2;

        $_POST["imageX"] = ($pWidth > $widthR ? $_POST["imageX"] - $diffW : $_POST["imageX"] + $diffW);
        $_POST["imageY"] = ($pHeight > $hegihtR ? $_POST["imageY"] - $diffH : $_POST["imageY"] + $diffH);
    }


    $dst_x = $src_x = $dst_y = $src_y = 0;

    if ($_POST["imageX"] > 0) {
        $dst_x = abs($_POST["imageX"]);
    } else {
        $src_x = abs($_POST["imageX"]);
    }
    if ($_POST["imageY"] > 0) {
        $dst_y = abs($_POST["imageY"]);
    } else {
        $src_y = abs($_POST["imageY"]);
    }


    $viewport = imagecreatetruecolor($_POST["viewPortW"], $_POST["viewPortH"]);
    setTransparency($image_p, $viewport, $ext);

    imagecopy($viewport, $image_p, $dst_x, $dst_y, $src_x, $src_y, $pWidth, $pHeight);
    imagedestroy($image_p);


    $selector = imagecreatetruecolor($_POST["selectorW"], $_POST["selectorH"]);
    setTransparency($viewport, $selector, $ext);
    imagecopy($selector, $viewport, 0, 0, $selectorX, $selectorY, $_POST["viewPortW"], $_POST["viewPortH"]);

    //$file = "tmp/test".time().".".$ext;
    parseImage($ext, $selector, WEB_PATH . $new_pic);
    imagedestroy($viewport);

    return true;
}

function determineImageScale($sourceWidth, $sourceHeight, $targetWidth, $targetHeight)
{
    $scalex = $targetWidth / $sourceWidth;
    $scaley = $targetHeight / $sourceHeight;
    return min($scalex, $scaley);
}

function returnCorrectFunction($ext)
{
    $function = "";
    switch ($ext) {
        case "png":
            $function = "imagecreatefrompng";
            break;
        case "jpeg":
            $function = "imagecreatefromjpeg";
            break;
        case "jpg":
            $function = "imagecreatefromjpeg";
            break;
        case "gif":
            $function = "imagecreatefromgif";
            break;
    }
    return $function;
}

function parseImage($ext, $img, $file = null)
{
    switch ($ext) {
        case "png":
            imagepng($img, ($file != null ? $file : ''));
            break;
        case "jpeg":
            imagejpeg($img, ($file ? $file : ''), 90);
            break;
        case "jpg":
            imagejpeg($img, ($file ? $file : ''), 90);
            break;
        case "gif":
            imagegif($img, ($file ? $file : ''));
            break;
    }
}

function setTransparency($imgSrc, $imgDest, $ext)
{

    if ($ext == "png" || $ext == "gif") {
        $trnprt_indx = imagecolortransparent($imgSrc);
        // If we have a specific transparent color
        if ($trnprt_indx >= 0) {
            // Get the original image's transparent color's RGB values
            $trnprt_color = imagecolorsforindex($imgSrc, $trnprt_indx);
            // Allocate the same color in the new image resource
            $trnprt_indx = imagecolorallocate($imgDest, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
            // Completely fill the background of the new image with allocated color.
            imagefill($imgDest, 0, 0, $trnprt_indx);
            // Set the background color for new image to transparent
            imagecolortransparent($imgDest, $trnprt_indx);
        } // Always make a transparent background color for PNGs that don't have one allocated already
        elseif ($ext == "png") {
            // Turn off transparency blending (temporarily)
            imagealphablending($imgDest, true);
            // Create a new transparent color for image
            $color = imagecolorallocatealpha($imgDest, 0, 0, 0, 127);
            // Completely fill the background of the new image with allocated color.
            imagefill($imgDest, 0, 0, $color);
            // Restore transparency blending
            imagesavealpha($imgDest, true);
        }
    }
}

//根据条件读取车详情
function getCarInfo($maps = '')
{

    $model = M("car");
    $info = M("car")->table(C('DB_PREFIX') . "car c")
        ->join(C('DB_PREFIX') . "car_shouxu cs on c.cid = cs.cid", "left")
        ->join(C('DB_PREFIX') . "car_attr ca on c.cid = ca.cid", "left")
        ->where($maps)->field(" c.*,cs.*,ca.* ")->find();

    return $info;
}

//查找我的竞拍列表
function getUserCarListByCondition($maps = '', $limit = '0,10', $orderby = "b.id desc", $ext_data = [])
{

    $model = M("bidding");

    if ($ext_data['only_get_count']) {

        $list = M("bidding")->table(C('DB_PREFIX') . "bidding b")
            ->join("  LEFT JOIN  " . C('DB_PREFIX') . "car c on b.cid = c.cid")->group("b.cid")
            ->where($maps)->count();
    } else {
        $list = M("bidding")->table(C('DB_PREFIX') . "bidding b")
            ->join("  LEFT JOIN  " . C('DB_PREFIX') . "car c on b.cid = c.cid")
            ->join("  LEFT JOIN  " . C('DB_PREFIX') . "car_shouxu cs on b.cid = cs.cid")
            ->join("  LEFT JOIN  " . C('DB_PREFIX') . "car_attr ca on b.cid = ca.cid")
            ->where($maps)->field("c.*,cs.*,ca.*,b.uid")//,b.price as user_max_price
            ->group("b.cid")->order($orderby)->limit($limit)->select();
    }

    return $list;
}

//根据条件获取车辆信息
function getCarListByCondition($maps = '', $limit = '0,10', $orderby = "c.cid desc", $ext_data = [])
{
    $model = M("car_owner");
    if ($ext_data['only_get_count']) {
        $list = M("car_owner")->table(C('DB_PREFIX') . "car_owner c")
            ->join("  INNER JOIN  " . C('DB_PREFIX') . "car_base cb on c.cid = cb.cid")
            ->join("  LEFT JOIN  " . C('DB_PREFIX') . "car_info ci on c.cid = ci.cid")
            ->join("  LEFT JOIN  " . C('DB_PREFIX') . "car_checker ch on c.cid = ch.cid")
            ->where($maps)->count();
    } else {
        $field = 'c.cid,c.channel,c.property,c.city_id,'
            . 'cb.bid,cb.series,cb.model,cb.custom_model,cb.level,cb.biansuqi_xingshi,cb.pailiang,'
            . 'cb.paifang_biaozhun,cb.biaozheng_licheng,cb.chudeng_riqi,'
            . 'ch.owner_min_price,ch.car_level,'
            . 'cx.guohu_cishu';
        $list = M("car_owner")->table(C('DB_PREFIX') . "car_owner c")
            ->join("  INNER JOIN  " . C('DB_PREFIX') . "car_base cb on c.cid = cb.cid")
            ->join("  LEFT JOIN  " . C('DB_PREFIX') . "car_checker ch on c.cid = ch.cid")
            ->join("  LEFT JOIN  " . C('DB_PREFIX') . "car_shouxu cx on c.cid = cx.cid")
            ->where($maps)->field($field)->order($orderby)->limit($limit)->select();
    }
    return $list;
}

//获得内容cdnurl
function get_content_cdnurl()
{
    $n = rand(6, 9);
    return '//img' . $n . '.isou365.cn/';
}

// 获取大文件cdnurl
function get_big_content_cdnurl()
{
    return 'http://img10.isou365.cn/';
}

//获得样式cdnurl
function get_style_cdnurl()
{
    $n = rand(1, 4);
    return 'http://img' . $n . '.isou365.cn/';
}

/**
 * 转换时间格式 eg,9点整转为上午,14点为下午
 *
 * @param        $date_str
 * @param string $type
 *
 * @return mixed
 */
function transform_date($date_str, $type = "1")
{
    $search = ["09:00:00", "14:00:00"];
    $replace = ["上午", "下午"];
    if ($type == 1) {
        return str_replace($search, $replace, $date_str);
    } else {
        return str_replace($replace, $search, $date_str);
    }
}

/**
 * @return string invite_code 生成唯一邀请码
 */
function gen_invite_code()
{
    return sprintf("%'x8x", crc32(microtime()));
}

/**
 * @param string $user_type
 *
 * @return string
 */
function gen_rand_user_name($user_type)
{
    return $user_type . "_" . time() . mt_rand(0, 999) . mt_rand(0, 999);
}

/**
 * 开奖啦 -- 计算中奖奖券号码
 *
 * @param float $sse    上证指数
 * @param float $szs    深证指数
 * @param int   $jq_num 抽奖券个数
 *                      return int $win_num 中奖号码
 */
function get_win_num($sse, $szs, $jq_num)
{
    $win_num = ($sse * $szs * 10000) % $jq_num + 1;
    return $win_num;
}

/**
 * 格式化奖券号码
 *
 * @param int $num
 *
 * @return int
 */
function lottory_ticket_format($num)
{
    return sprintf("%'06s", $num);
}

//获取渠道信息
function get_from()
{
    $from = M("come_from a")->field("a.from_id,a.from_name,b.from_name AS pname,b.from_id AS pid,b.sort AS psort")
        ->join('(SELECT from_id,from_name,sort FROM au_come_from WHERE pid=-2 AND is_delete=0) AS b ON a.pid=b.from_id')
        ->where("a.pid!=-2 AND a.is_delete=0")
        ->order("psort ASC,pid DESC")
        ->select();
    $show_from = [];
    foreach ($from as $key => $val) {
        $show_from[$val['from_id']] = $val['pname'] . '-' . $val['from_name'];
    }
    return $show_from;
}


////二维数组去掉重复值
function assoc_unique(&$arr, $key)
{
    $rAr = [];

    for ($i = 0; $i < count($arr); $i++) {
        if (!isset($rAr[$arr[$i][$key]])) {
            $rAr[$arr[$i][$key]] = $arr[$i];
        }
    }
    $arr = array_values($rAr);
}


/**
 * 精确到毫秒
 *
 * @return int
 */
function microtime_time()
{
    list($sec, $micro) = explode(" ", microtime());
    return ceil(((float)$sec + (float)$micro) * 1000);
}

/**
 * 文本级别日志
 *
 * @param string $type
 * @param array  $parame
 * @param string $path
 */
function info_log($type = '', $parame = [], $path = '/Run/Logs/')
{
    $time = date("Y-m-d");
    $path = ROOT_DIR . $path;
    $log_path = $path . $type . '/';
    if (!file_exists($log_path)) {
        @mkdir($log_path, 0777, true);
    }
    $file = $time . ".log";
    if (!is_writable($log_path . $file)) chmod($log_path . $file, 0777);
    file_put_contents($log_path . $file, "[" . date("Y-m-d H:i:s") . "]" . "|" . json_encode($parame) . "\r\n\n", FILE_APPEND);
}

/**
 * 产生固定长度的随机字符串
 *
 * @param      $len
 * @param null $chars
 *
 * @return string
 */
function genRandomChars($len, $chars = null)
{
    if (is_null($chars)) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    }
    mt_srand(10000000 * (double)microtime());
    for ($i = 0, $str = '', $lc = strlen($chars) - 1; $i < $len; $i++) {
        $str .= $chars[mt_rand(0, $lc)];
    }
    return $str;
}

/**
 * 产生一个四位的随机字符串
 *
 * @return string
 */
function gen4Chars()
{
    $strChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $numbers = "0123456789";
    $randomString = genRandomChars(3);
    if (ctype_digit($randomString)) {
        $randomString = $randomString . genRandomChars(1, $strChars);
    } elseif (ctype_alpha($randomString)) {
        $randomString = $randomString . genRandomChars(1, $numbers);
    } else {
        $randomString = $randomString . genRandomChars(1);
    }
    return $randomString;
}

/**
 * 产生一个单据编号
 *
 * @param $type
 * @param $subType
 *
 * @return string
 */
function genBillsNo($type, $subType)
{
    if ($subType < 10) $subType = "0" . $subType;
    return $type . $subType . date("Ymd") . gen4Chars();
}

/**
 * 获得图片完成链接
 *
 * @param $imgPath
 *
 * @return string
 */
function getFullUrl($imgPath)
{
    if (empty($imgPath)) {
        return '';
    }
    $str = substr($imgPath, 0, 4);
    if ($str != 'http') {
        $pres = C('CONTENT_IMG_PREFIX');
        $prefix = $pres[rand(0, 3)];
        $str = substr($imgPath, 0, 1);
        if ($str == '/') {
            $imgPath = $prefix . $imgPath;
        } else {
            $imgPath = $prefix . '/' . $imgPath;
        }
    }
    return $imgPath;
}

/**
 * 获取当前主机完整路径
 */
function getCurHostUrl()
{
    $curHostUrl = 'http';

    if ($_SERVER["HTTPS"] == "on") {
        $curHostUrl .= "s";
    }
    $curHostUrl .= "://";
    $serverName = $_SERVER['SERVER_NAME'] ? $_SERVER['SERVER_NAME'] : $_SERVER['SERVER_ADDR'];
    if ($_SERVER["SERVER_PORT"] != "80") {
        $curHostUrl .= $serverName . ":" . $_SERVER["SERVER_PORT"];
    } else {
        $curHostUrl .= $serverName;
    }
    return $curHostUrl;

}

/**
 *  通过Code获取Redis的Key
 *
 * @param $configKey
 * @param $code
 * @param $dataArr
 *
 * @return string
 */
function getRedisKeyByCode($configKey, $code, $dataArr)
{
    $arr = C($configKey)[$code];
    $key = $arr['key'];
    foreach ($dataArr as $itemKey => $itemValue) {
        $key = str_replace('#' . $itemKey . '#', $itemValue, $key);
    }
    return $key;
}

function requestByCurl($remoteServer, $postString)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $remoteServer);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json;charset=utf-8']);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postString);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $data = curl_exec($ch);
    curl_close($ch);

    return $data;
}

/**
 * 发送钉钉消息
 * @param string $content
 *
 * @return bool
 */
function sendDingDingMsg($content = '')
{
    $flag = true;
    $result = requestByCurl(C('WEB_HOOK'), json_encode(
            [
                'msgtype' => 'text',
                'text'    => [
                    'content' => $content
                ]
            ]
        )
    );
    $obj = (array)json_decode($result);
    if ($obj['errmsg'] != 'ok') {
        $flag = false;
    }
    return $flag;
}